package erfgame.core.world.terrain.rotated;

import java.awt.Dimension;
import java.awt.Point;


import erfgame.core.Rotation;
import erfgame.core.world.World;

public class RotatedWorld {
	private World world;
	private Rotation rotation;
	private Dimension tempDimension;
	
	public RotatedWorld( World world, Rotation rotation ) {
		this.world = world;
		this.rotation = rotation;
		this.tempDimension = new Dimension();
	}
	
	public World getOriginalWorld() {
		return world;
	}
	
	public Rotation getRotation( ) {
		return this.rotation;
	}
	
	public void setRotation( Rotation rotation ) {
		this.rotation = rotation;
	}

	public int getBlocksX() {
		return getBlocksX( tempDimension );
	}
	
	public int getBlocksX( Dimension tempDimension ) {
		return rotation.rotate(
				world.getBlocksX(), 
				world.getBlocksY(), 
				tempDimension
		).width;
	}
	
	public int getBlocksY() {
		return getBlocksY( tempDimension );
	}
	
	public int getBlocksY( Dimension tempDimension ) {
		return rotation.rotate(
				world.getBlocksX(), 
				world.getBlocksY(), 
				tempDimension
		).height;		
	}
	
	public int getBlocksZ() {
		return world.getBlocksZ();
	}
	
	public int getBlockWidth() {
		return getBlockWidth( tempDimension );
	}
	
	public int getBlockWidth( Dimension tempDimension ) {
		return rotation.rotate(
				world.getBlockWidth(), 
				world.getBlockHeight(), 
				tempDimension
		).width;
	}
	
	public int getBlockWidthShift() {
		return getBlockWidthShift( this.tempDimension );
	}
	
	public int getBlockWidthShift( Dimension tempDimension ) {
		return rotation.rotate(
				world.getBlockWidthShift(), 
				world.getBlockHeightShift(), 
				tempDimension
		).width;
	}
	
	public int getBlockWidthMask() {
		return getBlockWidthMask( this.tempDimension );
	}
	
	public int getBlockWidthMask( Dimension tempDimension ) {
		return rotation.rotate(
				world.getBlockWidthMask(), 
				world.getBlockHeightMask(), 
				tempDimension
		).width;
	}
	
	public int getBlockHeight() {
		return this.getBlockHeight( this.tempDimension );
	}
	
	public int getBlockHeight( Dimension tempDimension ) {
		return rotation.rotate(
				world.getBlockWidth(), 
				world.getBlockHeight(), 
				tempDimension
		).height;
	}
	
	public int getBlockHeightShift() {
		return getBlockHeightShift( this.tempDimension );
	}
	
	public int getBlockHeightShift( Dimension tempDimension ) {
		return rotation.rotate( 
				world.getBlockWidthShift(),
				world.getBlockHeightShift(),
				tempDimension
		).height;
	}
	
	public int getBlockHeightMask() {
		return getBlockHeightMask( tempDimension );
	}
	
	public int getBlockHeightMask( Dimension tempDimension ) {
		return rotation.rotate( 
				world.getBlockWidthMask(),
				world.getBlockHeightMask(),
				tempDimension
		).height;
		
	}
	
	public int getBlockDepth() {
		return world.getBlockDepth();
	}
	
	public int getXPathTilesPerBlock() {
		return getXPathTilesPerBlock( tempDimension );
	}
	
	public int getXPathTilesPerBlock( Dimension tempDimension ) {
		return this.rotation.rotate(
				world.getXPathTilesPerBlock(), 
				world.getYPathTilesPerBlock(), 
				tempDimension
		).width;
	}
	
	public int getXPathTilesPerBlockShift() {
		return this.getXPathTilesPerBlockShift( tempDimension );
	}
	
	public int getXPathTilesPerBlockShift( Dimension tempDimension ) {
		return this.rotation.rotate( 
				world.getXPathTilesPerBlockShift(), 
				world.getYPathTilesPerBlockShift(), 
				tempDimension
		).width;
	}
	
	public int getXPathTilesPerBlockMask() {
		return this.getXPathTilesPerBlockMask( this.tempDimension );
	}
	
	public int getXPathTilesPerBlockMask( Dimension tempDimension ) {
		return this.rotation.rotate( 
				world.getXPathTilesPerBlockMask(), 
				world.getYPathTilesPerBlockMask(), 
				tempDimension
		).width;		
	}
	
	public int getYPathTilesPerBlock() {
		return getYPathTilesPerBlock(tempDimension);
	}
	
	public int getYPathTilesPerBlock( Dimension tempDimension ) {
		return this.rotation.rotate(
				world.getXPathTilesPerBlock(),
				world.getYPathTilesPerBlock(), 
				tempDimension
		).height;
	}
	
	public int getYPathTilesPerBlockShift() {
		return getYPathTilesPerBlockShift( tempDimension );
	}
	
	public int getYPathTilesPerBlockShift( Dimension tempDimension ) {
		return this.rotation.rotate(
				world.getXPathTilesPerBlockShift(),
				world.getYPathTilesPerBlockShift(), 
				tempDimension
		).height;		 
	}
	
	public int getYPathTilesPerBlockMask() {
		return getYPathTilesPerBlockMask( tempDimension );
	}
	
	public int getYPathTilesPerBlockMask( Dimension tempDimension ) {
		return this.rotation.rotate(
				world.getXPathTilesPerBlockMask(),
				world.getYPathTilesPerBlockMask(), 
				tempDimension
		).height;		 
	}

	public int getXGridTilesPerBlock() {
		return getXGridTilesPerBlock( tempDimension );
	}
	
	public int getXGridTilesPerBlock( Dimension tempDimension ) {
		return this.rotation.rotate( 
				world.getXGridTilesPerBlock(), 
				world.getYGridTilesPerBlock(), 
				tempDimension
		).width;
	}
	
	public int getYGridTilesPerBlock() {
		return getYGridTilesPerBlock( tempDimension );
	}
	
	public int getYGridTilesPerBlock( Dimension tempDimension ) {
		return this.rotation.rotate( 
				world.getXGridTilesPerBlock(), 
				world.getYGridTilesPerBlock(), 
				tempDimension
		).height;		
	}

	public int getxGridTilesPerBlockShift() {
		return getxGridTilesPerBlockShift( tempDimension );
	}
	
	public int getxGridTilesPerBlockShift( Dimension tempDimension ) {
		return this.rotation.rotate( 
				world.getXGridTilesPerBlock(), 
				world.getYGridTilesPerBlock(), 
				tempDimension
		).width;
	}
	
	public int getyGridTilesPerBlockShift() {
		return getyGridTilesPerBlockShift( tempDimension );
	}
	
	public int getyGridTilesPerBlockShift( Dimension tempDimension ) {
		return this.rotation.rotate( 
				world.getXGridTilesPerBlock(), 
				world.getYGridTilesPerBlock(), 
				tempDimension
		).height;
	}

	public Point getWorldBlockMidPointTimes2() {
		Point original = world.getWorldBlockMidPointTimes2();
		switch( rotation.ordinal() ) {
		case Rotation.ORDINAL_0:
		case Rotation.ORDINAL_180:
		default:
			return original;
		case Rotation.ORDINAL_270:
		case Rotation.ORDINAL_90:
			return new Point( original.y, original.x );
		}
	}
	
	public Point getBlockMidPointTimes2() {
		Point original = world.getBlockMidPointTimes2();
		switch( rotation.ordinal() ) {
		case Rotation.ORDINAL_0:
		case Rotation.ORDINAL_180:
		default:
			return original;
		case Rotation.ORDINAL_270:
		case Rotation.ORDINAL_90:
			return new Point( original.y, original.x );
		}
	}
	
	public int getWorldWidth() {
		return getBlocksX() << getBlockWidthShift();
	}
	
//	public int getWorldWidth( Dimension tempDimension ) {
//		return rotation.rotate( 
//				world.getWorldWidth(), 
//				world.getWorldHeight(), 
//				tempDimension 
//		).width;
//	}
	
	public int getWorldHeight() {
		return getBlocksY() << getBlockHeightShift();
	}
	
//	public int getWorldHeight( Dimension tempDimension ) {
//		return rotation.rotate( 
//				world.getWorldWidth(), 
//				world.getWorldHeight(), 
//				tempDimension 
//		).height;
//	}
	
	public int getWorldDepth() {
		return world.getWorldDepth();
	}
}
